package com.yanqu.xiuxian.crosssystem.manger.elementalbonds.logic;

import com.yanqu.xiuxian.config.elementalbonds.enums.ElementalBondsOperateType;
import com.yanqu.xiuxian.crosssystem.manger.elementalbonds.data.ElementalBondsGameData;
import com.yanqu.xiuxian.crosssystem.manger.elementalbonds.data.ElementalBondsPlayerData;
import com.yanqu.xiuxian.crosssystem.manger.elementalbonds.data.ElementalBondsRoomData;
import com.yanqu.xiuxian.crosssystem.manger.elementalbonds.entity.ElementalBondsBlock;
import com.yanqu.xiuxian.crosssystem.manger.elementalbonds.param.ElementalBondsMoveParam;
import com.yanqu.xiuxian.crosssystem.manger.elementalbonds.result.ElementalBondsOperateResult;
import com.yanqu.xiuxian.server.protocol.GameErrorCode;

import java.util.*;

public class ElementalBondsMoveLogic {

    public static ElementalBondsOperateResult operate(ElementalBondsRoomData elementalBondsRoomData, boolean isPlayer1,
                                                      ElementalBondsMoveParam elementalBondsMoveParam, int guideDropNo, int roomRound) {
        ElementalBondsPlayerData elementalBondsPlayerData = isPlayer1 ? elementalBondsRoomData.getPlayer1() : elementalBondsRoomData.getPlayer2();
        ElementalBondsGameData elementalBondsGameData = elementalBondsRoomData.getGameData().clone();
        boolean stepMax = ElementalBondsGameLogic.isStepMax(elementalBondsRoomData.getModeId(), elementalBondsPlayerData);
        ElementalBondsOperateResult elementalBondsOperateResult = new ElementalBondsOperateResult(ElementalBondsOperateType.MOVE, stepMax, elementalBondsRoomData.getTurnPlayer());
        // 检查
        elementalBondsOperateResult.setRet(check(elementalBondsGameData, elementalBondsMoveParam, elementalBondsOperateResult));
        if (elementalBondsOperateResult.getRet() != GameErrorCode.E_SUCCESS_VALUE) {
            return elementalBondsOperateResult;
        }
        Random random = new Random();
        move(elementalBondsMoveParam, elementalBondsGameData, elementalBondsOperateResult, elementalBondsPlayerData,
                random, guideDropNo, roomRound, elementalBondsRoomData.getTurnPlayer());
        if (elementalBondsOperateResult.getRet() != GameErrorCode.E_SUCCESS_VALUE) {
            return elementalBondsOperateResult;
        }
        ElementalBondsSceneLogic.operateEnd(random, elementalBondsGameData, elementalBondsOperateResult);
        elementalBondsOperateResult.setElementalBondsGameData(elementalBondsGameData);
        return elementalBondsOperateResult;
    }

    public static int check(ElementalBondsGameData elementalBondsGameData, ElementalBondsMoveParam elementalBondsMoveParam, ElementalBondsOperateResult elementalBondsOperateResult) {
        // 检查能否移动
        int ret = ElementalBondsBlockLogic.checkExchange(elementalBondsGameData.getBlockList(), elementalBondsMoveParam);
        if (ret != GameErrorCode.E_SUCCESS_VALUE) {
            return ret;
        }
        // 移动后能否消除
        return ElementalBondsEliminateLogic.checkEliminate(elementalBondsGameData, elementalBondsMoveParam, elementalBondsOperateResult, null);
    }

    public static void move(ElementalBondsMoveParam elementalBondsMoveParam,
                            ElementalBondsGameData elementalBondsGameData, ElementalBondsOperateResult elementalBondsOperateResult, ElementalBondsPlayerData elementalBondsPlayerData,
                            Random random, int guideDropNo, int roomRound, int turnPlayer) {
        ElementalBondsBlockLogic.exchange(elementalBondsGameData.getBlockList(), elementalBondsMoveParam, elementalBondsOperateResult);
        // 消除
        ElementalBondsEliminateLogic.bigEliminate(elementalBondsGameData, elementalBondsPlayerData, elementalBondsMoveParam,
                new HashSet<>(), elementalBondsOperateResult, random, guideDropNo, roomRound, turnPlayer);
    }

    public static void moveChess(Random random, List<List<ElementalBondsBlock>> blockList, Set<ElementalBondsBlock> allMoveSet,
                                 List<ElementalBondsBlock> needMoveList, int[][] movePosArr, List<ElementalBondsBlock> curMoveList,
                                 List<ElementalBondsBlock> nextNeedMoveList, Set<ElementalBondsBlock> roundMoveSet) {
        for (ElementalBondsBlock block : needMoveList) {

            // 先按顺序移动
            boolean success = false;
            List<ElementalBondsBlock> exist = new ArrayList<>();
            for (int[] movePos : movePosArr) {
                int tmpX = block.getX() + movePos[0];
                int tmpY = block.getY() + movePos[1];
                if (ElementalBondsBlockLogic.exist(blockList, tmpX, tmpY)) {
                    ElementalBondsBlock tmpBlock = blockList.get(tmpY).get(tmpX);
                    exist.add(tmpBlock);
                    if (!allMoveSet.contains(tmpBlock)) { // 方块存在 && 未移动过 => 直接移动
                        if (block.getElementalBondsBlockType().getBigType().isBase()) {
                            allMoveSet.add(tmpBlock);
                            roundMoveSet.add(tmpBlock);
                            nextNeedMoveList.add(tmpBlock);
                            curMoveList.add(block);
                            curMoveList.add(tmpBlock);
                            success = true;
                            break;
                        }
                    }
                }
            }
            if (success) {
                continue;
            }

            // 移动失败，则优先非本轮移动的位置
            ArrayList<ElementalBondsBlock> list = new ArrayList<>(exist);
            list.removeAll(roundMoveSet);
            // 本轮位置为空，最后才是所有位置随机
            if (list.isEmpty()) {
                list = new ArrayList<>(exist);
            }

            if (!list.isEmpty()) {
                ElementalBondsBlock tmpBlock = list.remove(random.nextInt(list.size()));
                allMoveSet.add(tmpBlock);
                roundMoveSet.add(tmpBlock);
                nextNeedMoveList.add(tmpBlock);
                curMoveList.add(block);
                curMoveList.add(tmpBlock);
            }
        }
    }

}
